热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

创作者|正题_32.Python面向对象描述符运算符底层装饰器:闭包闭包参数内置装饰器类装饰器

篇首语:本文由编程笔记#小编为大家整理,主要介绍了32.Python面向对象描述符运算符底层装饰器:闭包-闭包参数-内置装饰器-类装饰器相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了32.Python面向对象描述符运算符底层装饰器:闭包-闭包参数-内置装饰器-类装饰器相关的知识,希望对你有一定的参考价值。



目录:


  • 每篇前言:
  • Python面向对象(五)
    • 1.1 描述符
    • 1.2 运算符底层调用的什么?
    • 1.3 装饰器
      • 第一部分——引入门
        • (1)首先、咱再看遍闭包是啥:
        • (2)然后,咱稍微高级点,看看闭包参数。
        • (3)最后,就来看看第一种装饰器:

      • 第二部分——类里面的内置装饰器
        • (1)引入
        • (2)第一个是把类里面的方法变为属性:
        • (3)静态方法
        • (4)第三个是类方法:

      • 第三部分——最后阶段
        • (1)类装饰器 必须使用__call__方法
        • (2)看看高级点的

      • 拓展一下呗——来个装饰器的习题




每篇前言:



  • 🏆🏆作者介绍:【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者


  • 🔥🔥本文已收录于Python全栈系列专栏:《Python全栈基础教程》
  • 🔥🔥热门专栏推荐:《Django框架从入门到实战》、《爬虫从入门到精通系列教程》、《爬虫高级》、《前端系列教程》、《tornado一条龙+一个完整版项目》。
  • 📝​📝本专栏面向广大程序猿,为的是大家都做到Python从入门到精通,同时穿插有很多很多习题,巩固学习。
  • 🎉🎉订阅专栏后可私聊进一千多人Python全栈交流群(手把手教学,问题解答); 进群可领取Python全栈教程视频 + 多得数不过来的计算机书籍:基础、Web、爬虫、数据分析、可视化、机器学习、深度学习、人工智能、算法、面试题等。
  • 🚀🚀加入我一起学习进步,一个人可以走的很快,一群人才能走的更远!





Python面向对象(五)

1.1 描述符



描述符协议:python描述符是一个“绑定行为”的对象属性,在描述符协议中,它可以通过方法重写属性的访问。这些方法有__get__(), __set__(), 和__delete__()
如果这些方法中的任何一个被定义在一个对象中,这个对象就是一个描述符


举例说明:

# -*- coding: utf-8 -*-
"""
__author__ = 孤寒者
"""

# 描述符:描述符就是类里面的属性base
# 控制实例对象a访问 这个属性 (base) 可以做一些额外的操作
# 描述符 定义了__get__ __set__ __delete__ 当中的一种
class Base:
def __get__(self,instance,owner):
print('恭喜玩家获得荒古宝典')
def __set__(self, instance,value):
print('强化%s'%value)
def __delete__(self,instance):
print('武器已经损坏')
class A:
base = Base()
#实例化
a = A()
a.base # __get__ 会直接输出__get__方法里面的内容
a.base = 50 # __set__ 会直接输出__set__方法里面的内容
del a.base # __delete__ 会直接输出__delete__方法里面的内容


1.2 运算符底层调用的什么?


  • +调用的是__add__

举例说明:

# -*- coding: utf-8 -*-
"""
__author__ = 孤寒者
"""

class A:
def __init__(self,num1,num2):
self.num1 = num1
self.num2 = num2
def __add__(self,other): #self 实例对象 ; other 另外一个实例对象
sum1 = self.num1 + other.num1
sum2 = self.num2 + other.num2
return sum1,sum2
a = A(1,2)
b = A(3,4)
print(a+b) #输出为 (4,6)

运算符方法(了解即可)

__add__(self,other) # x+y

__sub__(self,other) # x-y

__mul__(self,other) # x*y

__mod__(self,other) # x%y

__iadd__(self,other) # x+=y

__isub__(self,other) # x-=y

__radd__(self,other) # y+x

__rsub__(self,other) # y-x

__imul__(self,other) # x*=y

__imod__(self,other) # x%=y

1.3 装饰器

有这个玩意的原因:python是一个动态语言,因为一切都是对象。是一个脚本语言。


第一部分——引入门


(1)首先、咱再看遍闭包是啥:

# -*- coding: utf-8 -*-
"""
__author__ = 孤寒者
"""

#闭包
def fun1():
print('fun1')
def fun2():
print('fun2')
return fun2
#fun1()() ===> fun2()
a = fun1()
a() #会执行两个函数

(2)然后,咱稍微高级点,看看闭包参数。

这种方法比较麻烦,所以下面就引入了装饰器,和这个的功能一模一样,不过
简单了许多:

# -*- coding: utf-8 -*-
"""
__author__ = 孤寒者
"""

#闭包里面有参数 回调函数
def aa(fun): #fun = f1
print('------------aa')
def bb():
fun() #fun() = f1()
print('----------bb')
return bb
def f1():
print('this is f1')
def f2():
print('this is f2')
cc = aa(f1)
cc()


(3)最后,就来看看第一种装饰器:

# -*- coding: utf-8 -*-
"""
__author__ = 孤寒者
"""

# 装饰器 在不改变原有函数的基础上面增加额外的功能
# 装饰器
def aa(fun): #fun = f1
print('------------aa')
def bb():
fun() #fun() = f1()
print('----------bb')
return bb
# 装饰器 被装饰的函数名字(f1)会被当做参数传递给装饰函数(aa)
# 代码就是: aa(f1)
# 装饰函数(aa)执行完它自己内部的代码之后,会把它的结果返回给
# 被装饰的函数(f1)
# 代码就是: f1 = aa(f1)
# 然后下面又是f1() 就相当于 aa(f1)()
@aa # 就相当于 f1 = aa(f1) 要使用嵌套函数里面的内容 aa(f1)(),就是最后调用的时候f1加个括号
# 而注意函数外部的只要用到装饰器就会执行,而嵌套的内层函数需要调用才会执行,所以
# 用处就是把重要的东西写到嵌套的内层函数,在调用的时候才会执行
def f1():
print('this is f1')
def f2():
print('this is f2')
f1() #输出和上面一个一模一样


第二部分——类里面的内置装饰器


(1)引入

# -*- coding: utf-8 -*-
"""
__author__ = 孤寒者
"""

class Base:
def fun(self):
print('好好学习,天天向上')
b = Base()
b.fun() # 调用类里面的方法,就会执行类里面的方法fun,打印 好好学习,天天向上

正题:


(2)第一个是把类里面的方法变为属性:

# -*- coding: utf-8 -*-
"""
__author__ = 孤寒者
"""

class Base:
name = '孤寒者'
@property #将方法变为属性 更加简洁
def fun(self):
return('好好学习,天天向上')
b = Base()
print(b.name) #属性的使用不需要加括号;方法的使用才要加括号
print(b.fun) #现在类里面的方法fun就变成了类的属性


(3)静态方法


  • 第二个是把类里面的方法变为静态方法,让其可以像使用函数一样去使用,而不需要再实例化才能使用:

# -*- coding: utf-8 -*-
"""
__author__ = 孤寒者
"""

class Base:
@staticmethod #静态方法 方法能够像函数一样的去使用, 比如在类里面,你要写一些闭包什么的就可以在这里面写,相当于扩展了一些功能。
def fun2(): # 注意:这里已经不需要self 和class类断开联系
print('过年好,新年好')
#再来个不加装饰器的
def func(self):
print('这是普通方法')
Base.fun2() # fun2已经变为静态方法,可以像使用函数一样的使用
# 输出为: 过年好,新年好
# Base是类名;Base() 就是实例化
Base().func() # 而没有使用装饰器的方法就需要先实例化,才能去使用


(4)第三个是类方法:

# -*- coding: utf-8 -*-
"""
__author__ = 孤寒者
"""

class Base:
def func(self):
print('这是普通方法')
@classmethod
def fun3(cls): # 没有self 和实例无关,这是类方法 ; 有self的是实例方法,需要先实例化才能使用
print('cls类方法')
cls().func() # cls 代表类本身,即Base这个类
# 类方法的使用,也不用实例化 直接类名点方法
Base.fun3()


第三部分——最后阶段


(1)类装饰器 必须使用__call__方法

# -*- coding: utf-8 -*-
"""
__author__ = 孤寒者
"""

class Base:
def __init__(self,name):
self.name = name
def __call__(self,*args,**kwargs):
print('this is call')
@Base # func = Base(func) 被装饰函数(func)当做参数传递给装饰函数(Base)
def func():
print('this is func')
func() # 此处的括号就相当于 func() = Base(func)()
# __call__方法只要实例化就会被调用
#输出为: this is call


(2)看看高级点的

# -*- coding: utf-8 -*-
"""
__author__ = 孤寒者
"""

class Base:
def __init__(self,fun):
self.fun = fun
def __call__(self,*args,**kwargs):
self.fun() #就会打印 this is func
print('this is call')
def __str__(self):
return 'this is str'
@Base # func = Base(func) 相当于实例化 被装饰函数(func)当做参数传递给装饰函数(Base)
def func():
print('this is func')
func() # 此处的括号就相当于 func() = Base(func)()
# __call__方法只要实例化就会被调用
print(func) # 打印类的实例,就会调用类里面的__str__方法


拓展一下呗——来个装饰器的习题


  • 测试type和isinstance两个函数,哪个速度更加的快?

需要注意的是:程序运行速度比较快 只查看上面两个函数 运行一次的时间显示不出来效果,可以查看循环一万次的时间。

# -*- coding: utf-8 -*-
"""
__author__ = 孤寒者
"""

#time.time() 计算目前的时间 时间戳(格林威治时间, 1970.1.1到现在的总秒数)
import time
def funa(fun):
def funb():
a = time.time()
fun()
b = time.time()
print('函数运行了%s'%(b-a))
return funb
@funa
def f1():
for i in range(100000):
type(1)
f1()
@funa
def f2():
for i in range(100000):
isinstance(1,int)
f2()


推荐阅读
  • 深入解析 iOS Objective-C 中的对象内存对齐规则及其优化策略
    深入解析 iOS Objective-C 中的对象内存对齐规则及其优化策略 ... [详细]
  • Python与R语言在功能和应用场景上各有优势。尽管R语言在统计分析和数据可视化方面具有更强的专业性,但Python作为一种通用编程语言,适用于更广泛的领域,包括Web开发、自动化脚本和机器学习等。对于初学者而言,Python的学习曲线更为平缓,上手更加容易。此外,Python拥有庞大的社区支持和丰富的第三方库,使其在实际应用中更具灵活性和扩展性。 ... [详细]
  • 本文深入探讨了 MXOTDLL.dll 在 C# 环境中的应用与优化策略。针对近期公司从某生物技术供应商采购的指纹识别设备,该设备提供的 DLL 文件是用 C 语言编写的。为了更好地集成到现有的 C# 系统中,我们对原生的 C 语言 DLL 进行了封装,并利用 C# 的互操作性功能实现了高效调用。此外,文章还详细分析了在实际应用中可能遇到的性能瓶颈,并提出了一系列优化措施,以确保系统的稳定性和高效运行。 ... [详细]
  • 技术日志:深入探讨Spark Streaming与Spark SQL的融合应用
    技术日志:深入探讨Spark Streaming与Spark SQL的融合应用 ... [详细]
  • 【Python爬虫实操】 不创作小说,专精网站内容迁移,超高效!(含源代码)
    本文详细介绍了如何利用Python爬虫技术实现高效网站内容迁移,涵盖前端、后端及Android相关知识点。通过具体实例和源代码,展示了如何精准抓取并迁移网站内容,适合对Python爬虫实战感兴趣的开发者参考。 ... [详细]
  • HTML5大文件传输技术深度解析与实践分享
    本文深入探讨了HTML5在Web前端开发中实现大文件上传的技术细节与实践方法。通过实例分析,详细讲解了如何利用HTML5的相关特性高效、稳定地处理大文件传输问题,并提供了可供参考的代码示例和解决方案。此外,文章还讨论了常见的技术挑战及优化策略,旨在帮助开发者更好地理解和应用HTML5大文件上传技术。 ... [详细]
  • 在第七天的深度学习课程中,我们将重点探讨DGL框架的高级应用,特别是在官方文档指导下进行数据集的下载与预处理。通过详细的步骤说明和实用技巧,帮助读者高效地构建和优化图神经网络的数据管道。此外,我们还将介绍如何利用DGL提供的模块化工具,实现数据的快速加载和预处理,以提升模型训练的效率和准确性。 ... [详细]
  • 如何提升Python处理约1GB数据集时的运行效率?
    如何提升Python处理约1GB数据集时的运行效率?本文探讨了在后端开发中使用Python处理大规模数据集的优化方法。通过分析常见的性能瓶颈,介绍了多种提高数据处理速度的技术,包括使用高效的数据结构、并行计算、内存管理和代码优化策略。此外,文章还提供了在Ubuntu环境下配置和测试这些优化方案的具体步骤,适用于从事推荐系统等领域的开发者。 ... [详细]
  • 如何在 Java LinkedHashMap 中高效地提取首个或末尾的键值对? ... [详细]
  • MongoDB Aggregates.group() 方法详解与编程实例 ... [详细]
  • 在该项目中,参与者需结合历史使用模式和天气数据,以预测华盛顿特区自行车共享系统的租赁需求。数据分析部分首先涉及数据的收集,包括用户骑行记录和气象信息,为后续模型构建提供基础。通过深入的数据预处理和特征工程,确保数据质量和模型准确性,最终实现对自行车租赁需求的有效预测。 ... [详细]
  • Python正则表达式详解:掌握数量词用法轻松上手
    Python正则表达式详解:掌握数量词用法轻松上手 ... [详细]
  • 在前一篇文章中,我们介绍了如何使用Requests库发送GET请求。本文将深入探讨如何通过Requests库发送POST请求,包括参数格式、请求封装等关键技巧,并通过“历史上的今天”API实例进行详细说明。 ... [详细]
  • 在现代Web开发中,Ajax技术扮演着至关重要的角色。当我们使用传统的请求库(如requests)抓取网页时,有时会发现返回的数据与浏览器中显示的内容存在差异。这是因为许多动态内容是通过Ajax异步加载的,而requests等工具无法模拟这种异步行为。了解Ajax的工作原理及其在Web开发中的应用,可以帮助开发者更有效地抓取和处理动态生成的数据。 ... [详细]
  • 本文深入解析了 Python 爬虫技术在 B 站数据挖掘中的应用,通过分析海量用户行为和内容数据,揭示了热门 UP 主成功的背后因素。Python 作为一种强大的编程语言,其面向对象和解释执行的特点使其成为数据抓取和处理的理想选择。文章详细介绍了如何利用 Python 爬虫技术获取 B 站的数据,并通过数据分析方法,探讨了热门 UP 主的创作策略和互动模式,为内容创作者提供了有价值的参考。 ... [详细]
author-avatar
游太虚傲寰宇
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有